<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>从外部文件中加载数据</title>

    <script src="https://cdn.bootcss.com/d3/5.15.1/d3.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet">
    <style>
        h1,
        h2,
        h3 {
            font-weight: bold;
        }

        .h-bar {
            background-color: #ccc;
            text-align: right;
            margin-top: 3px;
        }

        .h-bar span {
            font-size: 14px;
            margin-right: 5px;
            color: #000;
            display: inline-block;
        }

        .name {
            float: left;
            margin-left: 2px;
        }

        .selected {
            background-color: #f08080;
        }

        footer {
            font-size: 12px;
            background-color: #ddd;
            text-align: center;
        }

        footer p {
            height: 5ch;
            line-height: 5ch;
        }

    </style>
</head>

<body>
    <header>
        <h1 class="text-center my-5">从外部文件中加载数据</h1>
    </header>
    <main>
        <section class="container">
            <div class="row justify-content-center">
                <div class="col-md-8" id="stage"></div>
            </div>
        </section>
        <section class="container my-5">
            <div class="row justify-content-center">
                <div class="control-group col-md-8">
                    <button class="btn btn-primary" onclick="sort(compareByScore)">
                        按成绩排序
                    </button>
                    <button class="btn btn-primary" onclick="select('1')">
                        新闻1班
                    </button>
                    <button class="btn btn-primary" onclick="select('2')">
                        新闻2班
                    </button>
                    <button class="btn btn-primary" onclick="select('3')">
                        广告1班
                    </button>
                    <button class="btn btn-primary" onclick="select('4')">
                        广告2班
                    </button>
                    <button class="btn btn-primary" onclick="select()">
                        Clear
                    </button>
                </div>
            </div>

        </section>
    </main>

    <footer class="container-fluid mt-5">
        <p>《网络编辑与制作》课程练习</p>
    </footer>

    <script>
        var raw;
        var data;

        async function getData() {
            raw = await d3.csv("5532937_202004272102272621.csv");
            data = clearData(raw);
            render(data);
        }

        function select(className) {
            render(data, className);
        }

        var compareByScore = function (a, b) {
            //
            return Number(a["成绩"]) < Number(b["成绩"]) ? -1 : 1;
        };

        function sort(comparator) {
            render(data, "", comparator);
        }

        function render(data, className, comparator) {
            let bars = d3.select("#stage").selectAll("div.h-bar").data(data);
            // enter
            bars
                .enter()
                .append("div")
                .attr("class", "h-bar")
                .style("width", function (d) {
                    return d["成绩"] * 7 + "px";
                })
                .html('<span class="name"></span>')
                .append("span")
                .attr("class", "score")
                .text(function (d) {
                    return d["成绩"];
                });

            // debugger;

            d3.selectAll("span.name")
                .data(data)
                .text(function (d) {
                    return d["name"];
                });
            // update
            d3.selectAll("div.h-bar").attr("class", "h-bar");

            // d3.select("body").selectAll("div.h-bar") //
            //     .data(data)
            //     .exit().remove();

            d3.select("body")
                .selectAll("div.h-bar")
                .filter(function (d, i) {
                    return d["班级"] == className;
                })
                .classed("selected", true);

            if (comparator) d3.select("body").selectAll("div.h-bar").sort(comparator);
        }

        function clearData(raw) {
            const data = [];
            var i = 0;
            raw.forEach(function (value) {
                // console.log(value['姓名']);
                data[i] = {};
                // debugger;
                name = getChinese(value["姓名"]);
                if (!isNameExist(name, data) && name != "") {
                    // 如果存在
                    data[i]["name"] = name;
                    data[i]["班级"] = value["班级"];
                    data[i]["答题时长"] = value["答题时长"];
                    data[i]["成绩"] = getBestScore(name, raw);
                    i++;
                }
            });
            // 删除最后一个元素
            data.pop();
            return data;
        }

        function getChinese(strValue) {
            if (strValue != null && strValue != "") {
                var reg = /[\u4e00-\u9fa5]/g;
                result = strValue.match(reg);
                // debugger
                if (result != null && result.length > 1) {
                    return result.join("");
                } else {
                    return "";
                }
            } else return "";
        }

        function getBestScore(name, obj) {
            let score = 0;
            for (const key in obj) {
                // console.log("第", key, '次对比前', score, obj[key]['总得分'], (Number(obj[key]['总得分']) > score));
                if (obj[key]["姓名"] == name && Number(obj[key]["总得分"]) > score) {
                    score = obj[key]["总得分"];
                    // console.log('对比后', key, score, obj[key]['总得分']);
                }
            }
            return score;
        }

        function isNameExist(name, obj) {
            for (var index in obj) {
                // console.log('key=', index, 'value=', obj[index]);
                if (obj[index]["name"] == name) {
                    return true;
                }
            }
            return false;
        }

    </script>
    <script>
        window.onload = getData();
    </script>
</body>

</html>
